//============================================================================================
/**
 * @file	phc_svdata.c
 * @brief	PHC関連セーブデータ
 * @author	AkitoMori GAME FREAK inc.
 * @date	2008.01.30
 */
//============================================================================================

#include "common.h"

#include "system/gamedata.h"
#include "savedata/savedata.h"
#include "savedata/phc_svdata.h"

#define POKEMON_DATA_SIZE		( 236 )		///< ポケモンデータのバイナリ上のサイズ
#define PHC_COURSE_MAX			(  32 )		///< コースフラグの最大アクセス範囲（u32なので）

//============================================================================================
//============================================================================================

///< PHCセーブデータ
struct PHC_SVDATA{
	u16 		flag;						///< PHC_NO_PLUG:紐つけしていない, PHC_NO_DEPSIT: 預けてない PHC_DEPOSIT: 預けてる
	u16			toBox;						///< ボックスＮＯ（手持ちの場合はRETURN_POSITION_TEMOTI）
	u8 			hidePoke[POKEMON_DATA_SIZE];///< ＰＨＣに預けることで隠れるポケモン(PPでもPPPでも）
	GF_DATE		DepositDate;				///< PHCにポケモンを預けた日付
	GF_DATE		ConnectDate;				///< PHCと交信した最後の日付
	u16			LastCourse;					///< 預けた時のコースNO
	u16			EndingFlag;					///< PHC内でエンディングをむかえたか？（0:まだ 1:むかえた）

	u8			PhcId[PHC_UNIQUE_ID_SIZE];	///< ユニークPHCID
	u16			DepositNum;					///< PHCにポケモンを預けた回数
	u16			padding2;					///< (定義無し)

	u32			TotalStep;					///< 歩いた総歩数
	u32			TotalWat;					///< 溜めたワット数
	u32			CourseOpenFlag;				///< 使用可能になったコースのbitフラグ（1:可能,0:不可能）

//	PHC_MAP_DATA MapData[PHC_MAP_NUM];		///< マップデータ

};


static int _check_hide_pokemon( PHC_SVDATA *sv );


//============================================================================================
/**
 * @brief セーブデータシステムが依存する関数
 * @param   sv		PHCセーブデータ
 *
 */
//============================================================================================
PHC_SVDATA * SaveData_GetPhcSaveData( SAVEDATA * sv )
{
	return SaveData_Get( sv, GMDATA_ID_PHC_SAVE );
}


//----------------------------------------------------------
/**
 * @brief	自分状態保持ワークのサイズ取得
 * @return	int		サイズ（バイト単位）
 */
//----------------------------------------------------------
int PhcSvData_GetWorkSize(void)
{
	return sizeof(PHC_SVDATA);
}

//==============================================================================
/**
 * @brief   PHC保存データの初期化
 *
 * @param   sv		PHCセーブデータ
 * @param   flag	0:完全初期化	1:コースフラグを残す初期化
 *
 * @retval  none
 */
//==============================================================================
void PhcSvData_Init( PHC_SVDATA *sv )
{

	// データ完全初期化
	MI_CpuClearFast( sv, sizeof(PHC_SVDATA));

	// 0番コースと1番コースは最初からオープンしている
	PhcSvData_SetCourseOpenFlag( sv, 0 );
	PhcSvData_SetCourseOpenFlag( sv, 1 );

}

//=============================================================================================
/**
 * @brief   PHC接続画面で使用するセーブデータ初期化処理（コースデータが消えない版）
 *
 * @param   sv		PHCセーブデータ
 */
//=============================================================================================
void PhcSvData_Clear( PHC_SVDATA *sv )
{
	u32 temp=0;

	// コースフラグを保存しておく場合の処理
	temp = sv->CourseOpenFlag;

	// セーブデータ初期化
	PhcSvData_Init( sv );

	// 保存していたコースフラグを代入
	sv->CourseOpenFlag = temp;

}



//=============================================================================================
/**
 * @brief	PHCにポケモンを預けた日を取得
 *
 * @param   sv		PHCセーブデータ
 *
 * @retval  GF_DATE		日付データ
 */
//=============================================================================================
GF_DATE PhcSvData_GetPhcDepositDate( PHC_SVDATA *sv )
{
	return sv->DepositDate;
}

//=============================================================================================
/**
 * @brief	PHCにポケモンを預けた日をセット
 *
 * @param   sv		PHCセーブデータ
 * @param   date	預けた日の日付データ
 */
//=============================================================================================
void PhcSvData_SetPhcDepositDate( PHC_SVDATA *sv, GF_DATE date )
{
	sv->DepositDate = date;
}

//=============================================================================================
/**
 * @brief	PHCと交信した最終日を取得
 *
 * @param   sv			PHCセーブデータ
 *
 * @retval  GF_DATE		最後にPHCと通信を行った日付データ
 */
//=============================================================================================
GF_DATE PhcSvData_GetPhcConnectDate( PHC_SVDATA *sv )
{
	return sv->ConnectDate;
}

//=============================================================================================
/**
 * @brief	PHCと交信した最終日を設定
 *
 * @param   sv		PHCセーブデータ
 * @param   date	日付データ
 */
//=============================================================================================
void PhcSvData_SetPhcConnectDate( PHC_SVDATA *sv, GF_DATE date )
{
	sv->ConnectDate = date;
}

//=============================================================================================
/**
 * @brief	PHCにポケモンを預けた回数を取得
 *
 * @param   sv		PHCセーブデータ
 *
 * @retval  int		預けた回数
 */
//=============================================================================================
int PhcSvData_GetPhcDepositNum( PHC_SVDATA *sv )
{
	return sv->DepositNum;
}

//=============================================================================================
/**
 * @brief	PHCにポケモンを預けた回数を増やす
 *
 * @param   sv		PHCセーブデータ
 */
//=============================================================================================
void PhcSvData_IncPhcDepositNum( PHC_SVDATA *sv )
{
	sv->DepositNum++;
}

//=============================================================================================
/**
 * @brief	総歩数と総ワット数をセット
 *
 * @param   sv		PHCセーブデータ
 * @param   step	総歩数
 * @param   wat		加算するワット数
 */
//=============================================================================================
void PhcSvData_SetTotalStepWat( PHC_SVDATA *sv, const u32 step, const u32 wat )
{
	// 歩数はPHCから総数が送られてくるのでそのまま保存
	sv->TotalStep 	= step;

	// ワットは足しこむ
	sv->TotalWat	+= wat;

	// ワットの上限設定
	if( sv->TotalWat >= PHC_WAT_MAX ){
		sv->TotalWat = PHC_WAT_MAX;
	}

}

//=============================================================================================
/**
 * @brief	総歩数と総ワット数を取得
 *
 * @param   sv		PHCセーブデータ
 * @param   step	総歩数
 * @param   wat		総ワット数
 */
//=============================================================================================
void PhcSvData_GetTotalStepWat( PHC_SVDATA *sv, u32 *step, u32 *wat )
{
	*step = sv->TotalStep;
	*wat  = sv->TotalWat;
}

//==============================================================================
/**
 * @brief   現在PHCに預けているかの情報を取得
 *
 * @param   sv		PHCセーブデータ
 * @param   flag	PHC_NO_PLUG:紐つけしていない, PHC_NO_DEPSIT: 預けてない PHC_DEPOSIT: 預けてる
 * @param   box		どこから預けたか（0:手持ち, 1-19:ボックス（1オリジン）
 *
 * @retval  none
 */
//==============================================================================
void PhcSvData_GetDepositInfo( PHC_SVDATA *sv, u16 *flag, u16 *box )
{
	GF_ASSERT( sv );
	*flag = sv->flag;
	*box  = sv->toBox;
}

//=============================================================================================
/**
 * @brief	PHCに預けてる情報の書き換えを行う
 *
 * @param   sv		PHCセーブデータ
 * @param   flag	PHC_NO_PLUG:DSに登録してない,	PHC_NO_DEPSIT:預けてない,	PHC_DEPOSIT:預けてる
 * @param   box		どのボックスから取り出したか?
 */
//=============================================================================================
void PhcSvData_SetDepositInfo( PHC_SVDATA *sv, int flag , int box )
{
	GF_ASSERT( sv );

	sv->flag = flag;
	sv->toBox  = box;
}

///< POKEMON_PASO_PARAM構造体のバイトサイズ
#define POKEMON_PASO_PARAM_SIZE	( 136 )

//=============================================================================================
/**
 * @brief	ボックスのポケモンデータを退避する
 *
 * @param   sv		PHCセーブデータ
 * @param   buf		POKEMON_PASO_PARAMのポインタ
 */
//=============================================================================================
void PhcSvData_SetPokemon( PHC_SVDATA *sv, const u8 *buf )
{
	MI_CpuCopyFast( buf, sv->hidePoke,  POKEMON_PASO_PARAM_SIZE );
}

//=============================================================================================
/**
 * @brief	隠しポケモンのデータ領域をクリアする
 *
 * @param   sv		PHCセーブデータ
 */
//=============================================================================================
void PhcSvData_ClearPokemon( PHC_SVDATA *sv )
{
	MI_CpuClearFast( sv->hidePoke, POKEMON_PASO_PARAM_SIZE );
}

//=============================================================================================
/**
 * @brief	隠してあるポケモンデータをコピーする
 *
 * @param   sv		PHCセーブデータ
 * @param   buf		ポケモンデータの出力先ポインタ
 *
 * @retval  int		1:データが存在する	0:データが存在しない
 */
//=============================================================================================
int PhcSvData_GetPokemon( PHC_SVDATA *sv, u8 *buf )
{
	// ポケモンデータが存在しているならコピーして返す
	if(_check_hide_pokemon( sv )){
		MI_CpuCopyFast( sv->hidePoke, buf,  POKEMON_PASO_PARAM_SIZE );
		return 1;
	}

	// 無かったら0を返す
	return 0;
}


//----------------------------------------------------------------------------------
/**
 * @brief	ポケモン保存領域が全部0かどうか調べる
 *
 * @param   sv		PHCセーブデータ
 *
 * @retval  int		0:入って無い	1:入ってる
 */
//----------------------------------------------------------------------------------
static int _check_hide_pokemon( PHC_SVDATA *sv )
{
	int i;
	for(i=0;i<POKEMON_PASO_PARAM_SIZE;i++){
		if(sv->hidePoke[i]!=0){
			break;
		}
	}

	if(i==POKEMON_PASO_PARAM_SIZE){
		// 全部０
		return 0;
	}

	// データ入ってる
	return 1;
}

//==============================================================================
/**
 * @brief   セーブデータから最後のコース名を取得
 *
 * @param   sv		PHCセーブデータ
 *
 * @retval  int		最後に預けたコースNO
 */
//==============================================================================
int PhcSvData_GetLastCourse( PHC_SVDATA *sv )
{
	return sv->LastCourse;
}

//==============================================================================
/**
 * @brief   預けたコースNO保存
 *
 * @param   sv			PHCセーブデータ
 * @param   course		コースNo
 *
 * @retval  none
 */
//==============================================================================
void PhcSvData_SettLastCourse( PHC_SVDATA *sv, int course )
{
	sv->LastCourse = course;
}

//==============================================================================
/**
 * @brief   PHCIDの先頭ポインタ取得
 *
 * @param   sv		PHCセーブデータ
 *
 * @retval  u8 *	40バイト続く配列のポインタ
 */
//==============================================================================
u8 *PhcSvData_GetIdPtr( PHC_SVDATA *sv )
{
	return sv->PhcId;
}

//==============================================================================
/**
 * @brief   コースがオープンしているか？
 *
 * @param   sv			PHCセーブデータ
 * @param   course_no	0-31
 *
 * @retval  int		使用可能になったコースのbitフラグ（1:可能,0:不可能）
 */
//==============================================================================
int PhcSvData_GetCourseOpenFlag( PHC_SVDATA *sv, int course_no )
{
	if( course_no>=PHC_COURSE_MAX ){
		return 0;
	}

	OS_Printf("course open = %08x\n", sv->CourseOpenFlag);
	// 対応したビットを返す
	return (sv->CourseOpenFlag>>course_no)&1;



}

//==============================================================================
/**
 * @brief   オープンしたコースをセットする
 *
 * @param   sv			PHCセーブデータ
 * @param   course_no	0-31
 *
 * @retval  none
 */
//==============================================================================
void PhcSvData_SetCourseOpenFlag( PHC_SVDATA *sv, int course_no )
{
	GF_ASSERT( course_no<PHC_COURSE_MAX );

	sv->CourseOpenFlag = ( sv->CourseOpenFlag | (1<<course_no) );

}

//=============================================================================================
/**
 * @brief	エンディングフラグの取得
 *
 * @param   sv		PHCセーブデータ
 */
//=============================================================================================
int PhcSvData_GetEndingFlag( PHC_SVDATA *sv )
{
	return sv->EndingFlag;
}


//=============================================================================================
/**
 * @brief	エンディングフラグを立てる
 *
 * @param   sv		PHCセーブデータ
 */
//=============================================================================================
void PhcSvData_SetEndingFlag( PHC_SVDATA *sv )
{
	// 落とすことは無いはずなので代入する値を引数にしていない
	sv->EndingFlag = 1;
}

#ifdef PM_DEBUG

//=============================================================================================
/**
 * @brief	コースフラグを初期状態にする
 *
 * @param   sv		PHCセーブデータ
 */
//=============================================================================================
void PhcSvData_InitCourseFlag( PHC_SVDATA *sv )
{
	sv->CourseOpenFlag = 0;

	PhcSvData_SetCourseOpenFlag( sv, 0 );
	PhcSvData_SetCourseOpenFlag( sv, 1 );

}

#endif